import java.util.Date;

public abstract class AbstractOrder implements StockValueObserver,
		OrderInterface {

	private int orderId;
	private OrderType orderType;
	private OrderCategory orderCategory;
	private int timestamp;
	private double orderPrice;
	private Date startTime;
	private Date endTime;
	private double priceLimit;
	private int quantity;
	private int fulfilledQuantity = 0;
	private int accountId;
	private int portfolioId;
	private double securityPrice;
	private int stockId;
	private int mutualFundId;
	private SecurityType securityType;
	private OrderState initializedState;
	private OrderState activeState;
	private OrderState partialState;
	private OrderState closedState;
	private OrderState orderState;

	public SecurityType getSecurityType() {
		return securityType;
	}

	public void setSecurityType(SecurityType securityType) {
		this.securityType = securityType;
	}

	public int getMutualFundId() {
		return mutualFundId;
	}

	public void setMutualFundId(int mutualFundId) {
		this.mutualFundId = mutualFundId;
	}

	public int getStockId() {
		return stockId;
	}

	public void setStockId(int stockId) {
		this.stockId = stockId;
	}

	public int getFulfilledQuantity() {
		return fulfilledQuantity;
	}

	public void setFulfilledQuantity(int fulfilledQuantity) {
		this.fulfilledQuantity = fulfilledQuantity;
	}

	public double getPriceLimit() {
		return priceLimit;
	}

	public void setPriceLimit(double priceLimit) {
		this.priceLimit = priceLimit;
	}

	public int getPortfolioId() {
		return portfolioId;
	}

	public void setPortfolioId(int portfolioId) {
		this.portfolioId = portfolioId;
	}

	public OrderState getOrderState() {
		return orderState;
	}

	public void setOrderState(OrderState orderState) {
		this.orderState = orderState;
	}

	public OrderState getInitializedState() {
		return initializedState;
	}

	public void setInitializedState(OrderState initializedState) {
		this.initializedState = initializedState;
	}

	public OrderState getActiveState() {
		return activeState;
	}

	public void setActiveState(OrderState activeState) {
		this.activeState = activeState;
	}

	public OrderState getPartialState() {
		return partialState;
	}

	public void setPartialState(OrderState partialState) {
		this.partialState = partialState;
	}

	public OrderState getClosedState() {
		return closedState;
	}

	public void setClosedState(OrderState closedState) {
		this.closedState = closedState;
	}

	public double getSecurityPrice() {
		return securityPrice;
	}

	public void setSecurityPrice(double securityPrice) {
		this.securityPrice = securityPrice;
	}

	public int getQuantity() {
		return quantity;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	public int getAccountId() {
		return accountId;
	}

	public void setAccountId(int accountId) {
		this.accountId = accountId;
	}

	public Date getStartTime() {
		return startTime;
	}

	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}

	public Date getEndTime() {
		return endTime;
	}

	public void setEndTime(Date endTime) {
		this.endTime = endTime;
	}

	public double getOrderPrice() {
		return orderPrice;
	}

	public void setOrderPrice(double orderPrice) {
		this.orderPrice = orderPrice;
	}

	public OrderCategory getOrderCategory() {
		return orderCategory;
	}

	public void setOrderCategory(OrderCategory orderCategory) {
		this.orderCategory = orderCategory;
	}

	public int getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(int timestamp) {
		this.timestamp = timestamp;
	}

	public int getOrderId() {
		return orderId;
	}

	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}

	public OrderType getOrderType() {
		return orderType;
	}

	public void setOrderType(OrderType orderType) {
		this.orderType = orderType;
	}

	public abstract void createOrder(int orderId, OrderCategory orderCategory,
			int accountId, int portfolioId);

	public abstract void display();

	public boolean hasSufficientBalance(int accountId, double price,
			int quantity) {
		double orderPrice = quantity * price;
		double accountBalance = 0;
		if (PortfolioRepository.getPortfolioRepository().getAccount(accountId) != null) {
			accountBalance = PortfolioRepository.getPortfolioRepository()
					.getAccount(accountId).getBalance();

			if (orderPrice > accountBalance) {
				System.out
						.println("Order cannot be placed due to insufficient Balance.");
				return false;
			}
		} else {
			System.out.println("Account does not exists!");
			return false;
		}
		return true;
	}

	public int compareTo(Object o) {
		if (this.securityPrice < ((AbstractOrder) o).securityPrice)
			return -1;
		if (this.securityPrice > ((AbstractOrder) o).securityPrice)
			return 1;
		else
			return 0;

	}

	public abstract AbstractOrder newStockOrder(AbstractOrder newOrder);
}
